﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

class FinalLevelBase : EnvBase
{
    private float maxHealth = 100;
    private float punchPower = 5;

    private Boolean isIntro;
    private Boolean isRaisingRobot;
    private Boolean isStartingFight;
    private Boolean isFighting;
    private Boolean isVictorious;
    private Boolean isFailure;

    private float robotBodyYPositionStart = 1100;
    private float robotLeftArmYPositionStart = 806;
    private float robotRightArmYPositionStart = 809;

    private float m_robotLeftArmYPosition;
    private float m_robotBodyYPosition;
    private float m_robotRightArmYPosition;

    private float raiseSpeed = 0.05f;

    private float robotBodyXPosition = 349;
    private float robotBodyYPosition = 589;
    private float robotLeftArmXPosition = 351;
    private float robotLeftArmYPosition = 295;
    private float robotRightArmXPosition = 293;
    private float robotRightArmYPosition = 298;
    private float robotLeftArmRotation = 0.0f;
    private float robotRightArmRotation = 0.0f;
    private Boolean rightArmActive = true;
    private Boolean leftArmActive = true;
    
    private Animation robotBodyAnim;
    private Animation robotRightArmAnim;
    private Animation robotLeftArmAnim;
    private Animation robotPowerBarAnim;
    private Animation robotPowerBarFrameAnim;
    private Animation robotPowerBarBGAnim;

    private Boolean robotIsShaking = false;
    private int robotCurrentShakeCount = 0;
    private float robotShakeDirection = 1;

    private float robotCurrentHealth;
    
    private float robotSwingSpeed = 0.2f;
    private float robotMaxRotation = (float)(120.0f * (Math.PI)/180);
    private float robotMinRotation = (float)(-45.0f * (Math.PI) / 180);
    private int shakeCountMax = 100;
    private int shakeDistance = 4;
    private float steveSwingSpeed;
    private float steveSwingSpeed1 = 0.02f;
    private float steveSwingSpeed2 = 0.12f;
    private float steveSwingSpeed3 = 0.14f;
    private float steveMaxRotation = (float)(45.0f * (Math.PI) / 180);
    private float steveMinRotation = (float)(-120.0f * (Math.PI) / 180);
    private float steveLeftArmDirection = 1;
    private float steveRightArmDirection = -1;

    private float steveBodyXPosition = 758;
    private float steveBodyYPosition = 589;
    private float steveLeftArmXPosition = 817;
    private float steveLeftArmYPosition = 254;
    private float steveRightArmXPosition = 780;
    private float steveRightArmYPosition = 258;
    private float steveLeftArmRotation = 37.0f;
    private float steveRightArmRotation = -37.0f;
    
    private Animation steveBodyAnim;
    private Animation steveRightArmAnim;
    private Animation steveLeftArmAnim;
    private Animation stevePowerBarAnim;
    private Animation stevePowerBarFrameAnim;
    private Animation stevePowerBarBGAnim;

    private Boolean steveIsShaking = false;
    private int steveCurrentShakeCount = 0;
    private float steveShakeDirection = 1;

    private float steveCurrentHealth;

    private Animation backgroundAnim;
    private Animation foregroundAnim;
    private Animation fightTextAnim;
    private Animation youWinTextAnim;
    private Animation youLoseTextAnim;

    private Random random = new Random();

    private int currentStartTimer = 0;
    private int startFightWaitTime = 100;

    
    

    public FinalLevelBase()
    {
        init();
    }

    private void init()
    {
        isIntro = true;
        isRaisingRobot = true;
        isStartingFight = false;
        isFighting = false;
        isVictorious = false;
        isFailure = false;

        loadAnims();
        steveCurrentHealth = maxHealth;
        robotCurrentHealth = maxHealth;
        steveSwingSpeed = steveSwingSpeed1;

        m_robotLeftArmYPosition = robotLeftArmYPositionStart;
        m_robotBodyYPosition = robotBodyYPositionStart;
        m_robotRightArmYPosition = robotRightArmYPositionStart;


        Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("robot_start")).sound, 1.0f);
        Game.getGame().getSoundManager().playSound(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.MENU_MUSIC).get("mainMenuMusic")).sound, 0.8f);
        
    }

    private void loadAnims()
    {

        robotBodyAnim = new Animation("robotBodyAnim", 0, false, 
            new ArrayList{new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("robotBody"),
                    new Rectangle(0, 0, 278, 555),
                    0,
                    new Vector2(139, 555))});
        robotLeftArmAnim = new Animation("robotLeftArmAnim", 0, false, 
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("robotLeftArm"),
                    new Rectangle(0, 0, 430, 355), 
                    0, 
                    new Vector2(58, 63))});
        robotRightArmAnim = new Animation("robotRightArmAnim", 0, false, 
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("robotRightArm"),
                    new Rectangle(0, 0, 438, 369), 
                    0, 
                    new Vector2(60, 65))
              });

        robotPowerBarFrameAnim = new Animation("finalLevelPowerBarFrame", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBarFrame"),
                    new Rectangle(0, 0, 424, 74), 
                    0, 
                    new Vector2(0, 0))
              });

        robotPowerBarAnim = new Animation("finalLevelPowerBar1", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBar1"),
                    new Rectangle(0, 0, 422, 73), 
                    0, 
                    new Vector2(0, 0))
              });

        robotPowerBarBGAnim = new Animation("finalLevelPowerBarBG", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBarBG"),
                    new Rectangle(0, 0, 424, 74), 
                    0, 
                    new Vector2(0, 0))
              });

        steveBodyAnim = new Animation("steveAnim", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("steveBody"),
                    new Rectangle(0, 0, 435, 555), 
                    0, 
                    new Vector2(217, 555))
              });
        steveRightArmAnim = new Animation("steveRightArmAnim", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("steveInnerArm"),
                    new Rectangle(0, 0, 344, 261), 
                    0, 
                    new Vector2(317, 19))
              });
        steveLeftArmAnim = new Animation("steveLeftArmAnim", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("steveOuterArm"),
                    new Rectangle(0, 0, 358, 298), 
                    0, 
                    new Vector2(332, 17))
              });

        stevePowerBarFrameAnim = new Animation("finalLevelPowerBarFrame", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBarFrame"),
                    new Rectangle(0, 0, 424, 73), 
                    0, 
                    new Vector2(0, 0))
              });

        stevePowerBarAnim = new Animation("finalLevelPowerBar2", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBar2"),
                    new Rectangle(0, 0, 422, 71), 
                    0, 
                    new Vector2(0, 0))
              });

        stevePowerBarBGAnim = new Animation("finalLevelPowerBarBG", 0, false,
            new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelPowerBarBG"),
                    new Rectangle(0, 0, 424, 74), 
                    0, 
                    new Vector2(0, 0))
              });


        backgroundAnim = new Animation("finalLevelBackground", 0, false, new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelBackground"),
                    new Rectangle(0, 0, 1024, 576), 
                    0, 
                    new Vector2(0, 0))
              });
        foregroundAnim = new Animation("foregroundAnim", 0, false, new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelForeground"),
                    new Rectangle(0, 0, 1024, 163), 
                    0, 
                    new Vector2(0, 0))
              });
        fightTextAnim = new Animation("fightTextAnim", 0, false, new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelFightText"),
                    new Rectangle(0, 0, 333, 150), 
                    0, 
                    new Vector2(166, 150))
              });
        youWinTextAnim = new Animation("youWinTextAnim", 0, false, new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelWinText"),
                    new Rectangle(0, 0, 534, 164), 
                    0, 
                    new Vector2(267, 164))
              });
        youLoseTextAnim = new Animation("youLoseTextAnim", 0, false, new ArrayList{
                new Frame(
                    Game.getGame().getAssetLibrary().get(AssetLibrary.assetType.FINAL_LEVEL).get("finalLevelLoseText"),
                    new Rectangle(0, 0, 534, 164), 
                    0, 
                    new Vector2(267, 164))
              });
    }

    public override void render()
    {
        

        if (isIntro)
        {
            if (isRaisingRobot)
            {
                m_robotRightArmYPosition -= 4.0f;
                m_robotBodyYPosition -= 4.0f;
                m_robotLeftArmYPosition -= 4.0f;

                 if (m_robotRightArmYPosition <= robotRightArmYPosition)
                {
                    m_robotRightArmYPosition = robotRightArmYPosition;
                    m_robotBodyYPosition = robotBodyYPosition;
                    m_robotLeftArmYPosition = robotLeftArmYPosition;
                    isRaisingRobot = false;
                    isStartingFight = true;
                    Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("final_game_bell")).sound, 1.0f);

                }

            } else if(isStartingFight){
                currentStartTimer ++;
                fightTextAnim.render(new Vector2(512, 288), 0.13f);
                if (currentStartTimer >= startFightWaitTime)
                {
                    isStartingFight = false;
                    isIntro = false;
                    isFighting = true;
                }
            }

            
        }

        if (isVictorious)
        {
            youWinTextAnim.render(new Vector2(512, 288), 0.13f);
            InputManager im = InputManager.getSingleton();
            im.update();

            if (im.getJustPressedControlState(InputManager.BACK_BUTTON) || im.getJustPressedControlState(InputManager.JUMP_BUTTON))
            {
                Game.getGame().getEnvStack().popAll(new MenuBase());
            }
        }
        else if (isFailure)
        {
            youLoseTextAnim.render(new Vector2(512, 288), 0.13f);
            InputManager im = InputManager.getSingleton();
            im.update();

            if (im.getJustPressedControlState(InputManager.BACK_BUTTON) || im.getJustPressedControlState(InputManager.JUMP_BUTTON))
            {
                Game.getGame().getEnvStack().popAll(new MenuBase());
            }
        }
        // drawbg

        backgroundAnim.render(new Vector2(0, 0), 0.24f);

        // draw robot1 and steve
        steveRightArmAnim.render(new Vector2(steveRightArmXPosition, steveRightArmYPosition), 0.231f, steveRightArmRotation);
        robotLeftArmAnim.render(new Vector2(robotLeftArmXPosition, m_robotLeftArmYPosition), 0.23f, robotLeftArmRotation);
        steveBodyAnim.render(new Vector2(steveBodyXPosition, steveBodyYPosition), 0.221f);
        robotBodyAnim.render(new Vector2(robotBodyXPosition, m_robotBodyYPosition), 0.22f);
        steveLeftArmAnim.render(new Vector2(steveLeftArmXPosition, steveLeftArmYPosition), 0.21f, steveLeftArmRotation);
        robotRightArmAnim.render(new Vector2(robotRightArmXPosition, m_robotRightArmYPosition), 0.201f, robotRightArmRotation);

        // draw steve

        // draw foreground art
        foregroundAnim.render(new Vector2(0, 413), 0.20f);

        // draw powerbars
        robotPowerBarBGAnim.render(new Vector2(39, 472), 0.19f);
        robotPowerBarAnim.render(new Vector2(40, 473), 0.18f, new Vector2(robotCurrentHealth / maxHealth, 1.0f));
        robotPowerBarFrameAnim.render(new Vector2(39, 472), 0.17f);

        stevePowerBarBGAnim.render(new Vector2(560, 472), 0.16f);
        stevePowerBarAnim.render(new Vector2(561, 473), 0.15f, new Vector2(steveCurrentHealth/maxHealth, 1.0f));
        stevePowerBarFrameAnim.render(new Vector2(560, 472), 0.14f);
        

    }

    public override void update(double dt)
    {
        if (isFighting)
        {

            InputManager.getSingleton().update();

            // listen for controls
#if DEBUG
            if (InputManager.getSingleton().getJustPressedControlState(InputManager.BACK_BUTTON))
            {
                m_parentStack.popAll(new MenuBase());
            }
#endif

            if (InputManager.getSingleton().getControlState(InputManager.DOWN_BUTTON) || InputManager.RIGHT_ANALOG_DOWN)
            {
                robotRightArmRotation += robotSwingSpeed;
                if (robotRightArmRotation > robotMaxRotation)
                {
                    robotRightArmRotation = robotMaxRotation;
                }

                if (robotRightArmRotation > 0.0f)
                {
                    rightArmActive = true;
                }
            }

            if (InputManager.getSingleton().getControlState(InputManager.UP_BUTTON) || InputManager.RIGHT_ANALOG_UP)
            {
                robotRightArmRotation -= robotSwingSpeed;
                if (robotRightArmRotation < robotMinRotation)
                {
                    robotRightArmRotation = robotMinRotation;
                    if (rightArmActive)
                    {
                        hitSteve();
                        rightArmActive = false;
                    }

                }
            }

            if (InputManager.getSingleton().getControlState(InputManager.JUMP_BUTTON) || InputManager.LEFT_ANALOG_DOWN)
            {
                robotLeftArmRotation += robotSwingSpeed;
                if (robotLeftArmRotation > robotMaxRotation)
                {
                    robotLeftArmRotation = robotMaxRotation;
                }

                if (robotLeftArmRotation > 0.0f)
                {
                    leftArmActive = true;
                }
            }

            if (InputManager.getSingleton().getControlState(InputManager.GRAB_BUTTON) || InputManager.LEFT_ANALOG_UP)
            {
                robotLeftArmRotation -= robotSwingSpeed;
                if (robotLeftArmRotation < robotMinRotation)
                {
                    robotLeftArmRotation = robotMinRotation;
                    if (leftArmActive)
                    {
                        hitSteve();
                        leftArmActive = false;
                    }
                }
            }
            // move steve's arms
            steveLeftArmRotation += steveSwingSpeed * steveLeftArmDirection;

            if (steveLeftArmRotation < steveMinRotation)
            {
                steveLeftArmRotation = steveMinRotation;
                steveLeftArmDirection *= -1;
            }
            else if (steveLeftArmRotation > steveMaxRotation)
            {
                steveLeftArmRotation = steveMaxRotation;
                steveLeftArmDirection *= -1;
                hitRobot();
            }

            steveRightArmRotation += steveSwingSpeed * steveRightArmDirection;
            if (steveRightArmRotation < steveMinRotation)
            {
                steveRightArmRotation = steveMinRotation;
                steveRightArmDirection *= -1;
            }
            else if (steveRightArmRotation > steveMaxRotation)
            {
                steveRightArmRotation = steveMaxRotation;
                steveRightArmDirection *= -1;
                hitRobot();
            }

            if (steveCurrentHealth < 50)
            {
                steveSwingSpeed = steveSwingSpeed3;
            }
            else if (steveCurrentHealth < 75)
            {
                steveSwingSpeed = steveSwingSpeed2;
            }
        }

    
    }

    private void hitRobot()
    {
        robotCurrentHealth -= punchPower;
        playPunch();
        if (robotCurrentHealth <= 0)
        {
            isFighting = false;
            isFailure = true;
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("game_lose")).sound, 1.0f);
        }
    }

    private void hitSteve()
    {
        steveCurrentHealth -= punchPower;
        playPunch();
        if (steveCurrentHealth <= 0)
        {
            isFighting = false;
            isVictorious = true;
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("game_victory")).sound, 1.0f);
        }
    }

    private void playPunch()
    {
        int randomNum = random.Next(3);
        if (randomNum == 0)
        {
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("punch1")).sound, 1.0f);
        } else if (randomNum == 1)
        {
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("punch2")).sound, 1.0f);
        } else if (randomNum == 2)
        {
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("punch3")).sound, 1.0f);
        } else if (randomNum == 3)
        {
            Game.getGame().getSoundManager().playOneSoundEffect(((AudioAsset)Game.getGame().getAssetLibrary().getAudio(AssetLibrary.audioType.SOUND_EFFECT).get("punch4")).sound, 1.0f);
        } 
    }
}
